#include "UserInterface.h"

//for the window handle
#include "Visualisation.h"
#include "WorldModel.h"
#include <sstream>

//for the input devices
#include "InputKeyboard.h"
#include "InputMouse.h"
#include "InputXBoxController.h"
#include <Xinput.h>

#include <assert.h>

CUserInterface* CUserInterface::instance=0;

CUserInterface::CUserInterface(void):m_indexInputKeyboard(-1), m_indexInputMouse(-1), m_indexInputXBoxController(-1),
				m_diObject(0), m_indexTextureMenu(-1)
{
	m_tableIntToDIK[0]=DIK_A;
	m_tableStringToInt[0]="A";
	m_tableIntToDIK[1]=DIK_B;
	m_tableStringToInt[1]="B";
	m_tableIntToDIK[2]=DIK_C;
	m_tableStringToInt[2]="C";
	m_tableIntToDIK[3]=DIK_D;
	m_tableStringToInt[3]="D";
	m_tableIntToDIK[4]=DIK_E;
	m_tableStringToInt[4]="E";
	m_tableIntToDIK[5]=DIK_F;
	m_tableStringToInt[5]="F";
	m_tableIntToDIK[6]=DIK_G;
	m_tableStringToInt[6]="G";
	m_tableIntToDIK[7]=DIK_H;
	m_tableStringToInt[7]="H";
	m_tableIntToDIK[8]=DIK_I;
	m_tableStringToInt[8]="I";
	m_tableIntToDIK[9]=DIK_J;
	m_tableStringToInt[9]="J";
	m_tableIntToDIK[10]=DIK_K;
	m_tableStringToInt[10]="K";
	m_tableIntToDIK[11]=DIK_L;
	m_tableStringToInt[11]="L";
	m_tableIntToDIK[12]=DIK_M;
	m_tableStringToInt[12]="M";
	m_tableIntToDIK[13]=DIK_N;
	m_tableStringToInt[13]="N";
	m_tableIntToDIK[14]=DIK_O;
	m_tableStringToInt[14]="O";
	m_tableIntToDIK[15]=DIK_P;
	m_tableStringToInt[15]="P";
	m_tableIntToDIK[16]=DIK_Q;
	m_tableStringToInt[16]="Q";
	m_tableIntToDIK[17]=DIK_R;
	m_tableStringToInt[17]="R";
	m_tableIntToDIK[18]=DIK_S;
	m_tableStringToInt[18]="S";
	m_tableIntToDIK[19]=DIK_T;
	m_tableStringToInt[19]="T";
	m_tableIntToDIK[20]=DIK_U;
	m_tableStringToInt[20]="U";
	m_tableIntToDIK[21]=DIK_V;
	m_tableStringToInt[21]="V";
	m_tableIntToDIK[22]=DIK_W;
	m_tableStringToInt[22]="W";
	m_tableIntToDIK[23]=DIK_X;
	m_tableStringToInt[23]="X";
	m_tableIntToDIK[24]=DIK_Y;
	m_tableStringToInt[24]="Y";
	m_tableIntToDIK[25]=DIK_Z;
	m_tableStringToInt[25]="Z";
	m_tableIntToDIK[26]=DIK_LEFT;
	m_tableStringToInt[26]="LEFT";
	m_tableIntToDIK[27]=DIK_RIGHT;
	m_tableStringToInt[27]="RIGHT";
	m_tableIntToDIK[28]=DIK_UP;
	m_tableStringToInt[28]="UP";
	m_tableIntToDIK[29]=DIK_DOWN;
	m_tableStringToInt[29]="DOWN";
	m_tableIntToDIK[30]=0;
	m_tableStringToInt[30]="LeftButton";
	m_tableIntToDIK[31]=1;
	m_tableStringToInt[31]="RightButton";
	m_tableIntToDIK[32]=7;
	m_tableStringToInt[32]="RightStick";
	m_tableIntToDIK[33]=3;
	m_tableStringToInt[33]="LeftStick";
	m_tableIntToDIK[34]=XINPUT_GAMEPAD_A;
	m_tableStringToInt[34]="ButtonA";
	m_tableIntToDIK[35]=XINPUT_GAMEPAD_B;
	m_tableStringToInt[35]="ButtonB";
	m_tableIntToDIK[36]=XINPUT_GAMEPAD_X;
	m_tableStringToInt[36]="ButtonX";
	m_tableIntToDIK[37]=XINPUT_GAMEPAD_Y;
	m_tableStringToInt[37]="ButtonY";
	m_tableIntToDIK[38]=XINPUT_GAMEPAD_RIGHT_SHOULDER;
	m_tableStringToInt[38]="RightShoulder";
	m_tableIntToDIK[39]=XINPUT_GAMEPAD_LEFT_SHOULDER;
	m_tableStringToInt[39]="LeftShoulder";
	m_tableIntToDIK[40]=XINPUT_GAMEPAD_RIGHT_THUMB;
	m_tableStringToInt[40]="RightThumb";
	m_tableIntToDIK[41]=XINPUT_GAMEPAD_LEFT_THUMB;
	m_tableStringToInt[41]="LeftThumb";
	m_tableIntToDIK[42]=XINPUT_GAMEPAD_BACK;
	m_tableStringToInt[42]="Back";
	m_tableIntToDIK[43]=XINPUT_GAMEPAD_START;
	m_tableStringToInt[43]="Start";

	


}

CUserInterface::~CUserInterface(void)
{
	for(vector<CInput*>::iterator i=m_inputDevicesVector.begin(); i!=m_inputDevicesVector.end(); i++)
	{
		if((*i)!=0)
		{
			delete (*i);
			(*i)=0;
		}
	}
	if(m_diObject!=0)
		m_diObject->Release();
}

CUserInterface* CUserInterface::getInstance(void)
{
	if(instance==0)
		instance = new CUserInterface();

	return instance;
}
void CUserInterface::close()
{
	delete instance;
	instance=0;
}

bool CUserInterface::initialiseInputs(HINSTANCE instance)
{
	//create the main direct input object
	HRESULT hr = DirectInput8Create(instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_diObject, NULL); 
	if(FAILED(hr))
		return false;

	//create the keyboard device
	CInput* keyboard = new CInputKeyboard();
	if(!keyboard->initialise(m_diObject))
		return false;

	//add the device to the vector
	m_indexInputKeyboard=(int)m_inputDevicesVector.size();
	m_inputDevicesVector.push_back(keyboard);
	
	//create the mouse device
	CInput* mouse = new CInputMouse();
	if(!mouse->initialise(m_diObject))
		return false;

	//add the device to the vector
	m_indexInputMouse=(int)m_inputDevicesVector.size();
	m_inputDevicesVector.push_back(mouse);

	//create a xbox device
	CInput* xbox=new CInputXBoxController();
	if(!xbox->initialise(m_diObject))
		return false;

	//add it to the vector of device
	m_indexInputXBoxController=(int)m_inputDevicesVector.size();
	m_inputDevicesVector.push_back(xbox);

	return true;
}

void CUserInterface::initialiseMenu(int indexTexture)
{
	assert(indexTexture>=0);

	m_indexTextureMenu=indexTexture;
}

bool CUserInterface::loadActionMapping(string filename)
{
	//open the xml file
	Document controlsDocument;
	try
	{
		controlsDocument.Read(filename.c_str());
	}
	catch(TXF::InvalidFileFormatException) //if the file doesn't exist
	{
		return false;
	}
	Element root = controlsDocument.RootElement();
	list<Element> control=root.Children();
	
	list<Element>::iterator i=control.begin();
	while(i!=control.end())
	{
		if(i->Name()=="keyboard")
		{
			if(m_indexInputKeyboard!=-1)
			{
				if(!m_inputDevicesVector[m_indexInputKeyboard]->initialiseActionMapping(*i))
					return false;
			}
		}
		else if(i->Name()=="mouse")
		{
			if(m_indexInputMouse!=-1)
			{
				if(!m_inputDevicesVector[m_indexInputMouse]->initialiseActionMapping(*i))
					return false;
			}
		}
		else if(i->Name()=="xBoxController")
		{
			if(m_indexInputXBoxController!=-1)
			{
				if(!m_inputDevicesVector[m_indexInputXBoxController]->initialiseActionMapping(*i))
					return false;
			}
		}
		else
			return false;

		i++;
	}
	return true;
}

void CUserInterface::doUpdateInputs()
{
	for(vector<CInput*>::iterator i=m_inputDevicesVector.begin(); i!=m_inputDevicesVector.end(); i++)
	{
		(*i)->doUpdate();
	}
}

int CUserInterface::getDirectInputValue(string input)
{
	bool found=false;
	int count=0;
	while(!found && count<NUMBER_OF_INPUTS)
	{
		if(m_tableStringToInt[count]==input)
			found=true;
		else
			count++;
	}
	return m_tableIntToDIK[count];
}

void CUserInterface::displayHUD()
{
	//get the position
	RECT rct;
	rct.left=20;
	rct.right=800;
	rct.top=VIS->getWindowHeight()-100;
	rct.bottom=rct.top+50;

	//color
	D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,255); 

	//create the string
	float health=WORLDMODEL->getPlayerHealth();
	ostringstream buffer;
	buffer<<health;
	string text;
	text.clear();
	text="LIFE : ";
	text.append(buffer.str());

	//draw the text
	VIS->displayText(&rct, fontColor, text);
}

void CUserInterface::displayGameOver()
{
	//get the position
	RECT rct;
	rct.left=VIS->getWindowWidth()/2-80;
	rct.right=rct.left+300;
	rct.top=VIS->getWindowHeight()/2-50;
	rct.bottom=rct.top+50;

	//color
	D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,255);

	string text("GAME OVER");

	VIS->displayText(&rct, fontColor, text);
}

void CUserInterface::displayMenu()
{
	VIS->displayTexture(m_indexTextureMenu, D3DXVECTOR3(0, 0, 0));
}